package com.joshua.spring.gateway.service.impl;

import com.joshua.spring.gateway.constant.TipMessageConstants;
import com.joshua.spring.gateway.repo.CachedRouteDefinitionRepository;
import com.joshua.spring.gateway.service.DynamicRouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

/**
 * description 动态路由service
 * package com.joshua.spring.com.joshua.spring.gateway.service
 * classname  DynamicRouteServiceImpl
 *
 * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
 * @date 2020/2/10 10:23
 */
@Slf4j
@Service
public class DynamicRouteServiceImpl implements DynamicRouteService {

    @Autowired
    @Qualifier(CachedRouteDefinitionRepository.CACHED_ROUTE_DEFINITION_REPOSITORY)
    private RouteDefinitionRepository routeDefinitionWriter;

    private ApplicationEventPublisher publisher;

    private void notifyChanged() {
        log.info("Publish refresh route event");
        publisher.publishEvent(new RefreshRoutesEvent(this));
    }


    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        publisher = applicationEventPublisher;
    }

    /**
     * description: 增加路由
     *
     * @param definition
     * @return {@link String}
     * @throws
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/2/10 10:27
     */
    @Override
    public String add(RouteDefinition definition) {
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        //将新增的路由配置信息发布到redis监听
        notifyChanged();
        return TipMessageConstants.SUCCESS;
    }

    /**
     * description: 更新路由
     *
     * @param definition
     * @return {@link String}
     * @throws
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/2/10 10:28
     */
    @Override
    public String update(RouteDefinition definition) {
        try {
            routeDefinitionWriter.delete(Mono.just(definition.getId()));
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            notifyChanged();
            return TipMessageConstants.SUCCESS;
        } catch (Exception e) {
            log.error("update route definition ->[id:{}] fail,", definition.getId(), e);
            return String.format("update route [%s] definition fail", definition.getId());
        }
    }

    /**
     * description: 删除路由
     *
     * @param id
     * @return {@link Mono<ResponseEntity<Object>>}
     * @throws
     * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
     * @date 2020/2/10 10:28
     */
    @Override
    public String delete(String id) {
        routeDefinitionWriter.delete(Mono.just(id));
        notifyChanged();
        return id;
    }
}
